﻿#include "GY_IdTableView.h"
#include <QHeaderView>
#include <ItemView/FilterModule/CustomFilterModule.h>

GY_IdTableView::GY_IdTableView(QWidget *parent)
    : QTableView(parent)
{
    m_pModel= new QStandardItemModel(this);
    //创建自定义代理模型
    m_pFilter = new CustomFilterModule(this);
    m_pFilter->setSourceModel(m_pModel);
    this->setModel(m_pFilter);
    m_pLastSelectItme=nullptr;
    //单元格内容修改信号
    connect(m_pModel,&QStandardItemModel::itemChanged,this,&GY_IdTableView::dataChangedSlot);
}

GY_IdTableView::GY_IdTableView(QStandardItemModel *pModel, QWidget *parent)
    : QTableView(parent)
{
    m_pModel = pModel;
    //创建自定义代理模型
    m_pFilter = new CustomFilterModule(this);
    m_pFilter->setSourceModel(m_pModel);
    this->setModel(m_pFilter);
    m_pLastSelectItme=nullptr;
    //单元格内容修改信号
    connect(m_pModel,&QStandardItemModel::itemChanged,this,&GY_IdTableView::dataChangedSlot);
}
/**
 * @brief setColumnCount 设置列数
 * @param columnCount 添加的列数
 */
void GY_IdTableView::setColumnCount(const int columnCount)
{
    if(columnCount<=0||m_pModel->columnCount()==columnCount)
    {
        return;
    }
    if(!m_pModel->columnCount()){ //如果列表为空
        m_pModel->setColumnCount(columnCount);
        QStringList headNames; //创建表名
        for(int i=0; i<columnCount;i++)
        {
            headNames << QString("标题%1").arg(i+1);
        }
        m_pModel->setHorizontalHeaderLabels(headNames); //将表名导入列表中
    }
    else //如果列表存在数据
    {
        if(m_pModel->columnCount()<columnCount)
        {
            QList<QStandardItem*> headNames;
            for(int i=columnCount-m_pModel->columnCount();i<columnCount;i++)
            {
                headNames<<new QStandardItem(QString("标题%1").arg(i+1));
            }
            m_pModel->appendColumn(headNames);
            for(int i=columnCount-m_pModel->columnCount();i<columnCount;i++)
            {
                foreach(QList<QStandardItem*> dataItemList,m_RowDataInfoMap)
                {
                    //找到所在行
                    int row=dataItemList[0]->row();
                    QStandardItem* pItem=new QStandardItem;
                    dataItemList.append(pItem);
                    m_pModel->setItem(row,i,pItem);
                }
            }
        }
        else
        {
            for(int i=m_pModel->columnCount()-columnCount;i<m_pModel->columnCount();i++)
            {
                m_pModel->takeColumn(i);
                foreach(QList<QStandardItem*> dataItemList,m_RowDataInfoMap)
                {
                    delete dataItemList[i];
                    dataItemList.removeAt(i);
                }
            }
        }
    }
}
/**
 * @brief addColumn 添加空白列
 * @param columnName 添加的列名
 */
void GY_IdTableView::addColumn(const QString &columnName)
{
    if(columnName==nullptr) //设置列名为空无效
    {
        return;
    }
    int column = m_pModel->columnCount();
    m_pModel->setHorizontalHeaderItem(column,new QStandardItem(columnName));
    foreach(QList<QStandardItem*> dataItemList,m_RowDataInfoMap)
    {
        int row=dataItemList[0]->row();
        QStandardItem* pItem=new QStandardItem;
        m_pModel->setItem(row,dataItemList.size(),pItem);
        dataItemList.append(pItem);
    }
}
/**
 * @brief insterColumn 插入列
 * @param index 插入在第几列
 * @param columnName 插入的列名
 * @return 返回插入列是否成功
 */
bool GY_IdTableView::insterColumn(const int index, const QString &columnName)
{
    if(!m_pModel || index<0 || index>m_pModel->columnCount())
    {
        return false;
    }
    QList<QStandardItem*> listItem;
    for(int i=0;i<m_pModel->rowCount();i++)
    {
        QStandardItem* pRowItem = m_pModel->item(i);
        listItem<<pRowItem;
    }
    m_pModel->insertColumn(index,listItem);
    QStandardItem* pitem = new QStandardItem(columnName);
    m_pModel->setHorizontalHeaderItem(index,pitem);
    for(QMap<QVariant,QList<QStandardItem*>>::iterator iter = m_RowDataInfoMap.begin(); iter != m_RowDataInfoMap.end();){
        int row=iter.value()[0]->row();
        QStandardItem* pItem=new QStandardItem;
        if(index == 0){
            pItem->setData(iter.value()[0]->data(),TableDataType::RowIdData);
        }
        m_pModel->setItem(row,index,pItem);
        iter.value().insert(index,pItem);
        iter++;
    }
    return true;
}

/**
 * @brief deleteColumn 删除列
 * @param index 列索引
 * @return 返回删除列是否成功
 */
bool GY_IdTableView::deleteColumn(const int index)
{
    if(m_pModel==nullptr ||index<0 || index>m_pModel->columnCount())
    {
        return false;
    }
    QList<QStandardItem*> removItems=m_pModel->takeColumn(index);
    //删除信息记录
    for(QMap<QVariant,QList<QStandardItem*>>::iterator iter = m_RowDataInfoMap.begin(); iter != m_RowDataInfoMap.end();){
        delete iter.value()[index];
        iter.value().removeAt(index);
        iter++;
    }
    //如果判定已经删除了所有列便清空Map
    if(!m_pModel->columnCount())
    {
        m_RowDataInfoMap.clear();
    }
    //如果删除的是第一列将RowID重新赋值给新的第一列
    else if(!index)
    {
        foreach(QStandardItem* pItem,removItems)
        {
            QVariant rowID=pItem->data(TableDataType::RowIdData);
            if(m_RowDataInfoMap.contains(rowID))
            {
                m_RowDataInfoMap[rowID][0]->setData(rowID,TableDataType::RowIdData);
            }
        }
    }
    return true;
}
/**
 * @brief setColumnHeadName  设置列头名称
 * @param nameList  要修改的列名集
 */
void GY_IdTableView::setColumnHeadName(const QStringList &nameList)
{
    if(nameList.size()<0 || !m_pModel)
    {
        return;
    }
    QStringList headNames;
    for(int i=0;i<m_pModel->columnCount();i++)
    {
        if(i<nameList.size())//如果原列表列数小于新设置的列名数量
        {
            headNames<< nameList.at(i);
        }
        else
        {
            headNames<< m_pModel->horizontalHeaderItem(i)->text();//将原列表列名补充进新列名中
        }
    }
    m_pModel->setHorizontalHeaderLabels(headNames); //将列名导入列表中
}
/**
 * @brief setColumnHeadName  修改某一列列名
 * @param index  要修改名字在第几列
 * @param headName  要修改成的名字
 */
void GY_IdTableView::setColumnHeadName(const int index, const QString &headName)
{
    if(index>=m_pModel->columnCount()||index<0)
    {
        return;
    }
    QStandardItem* pitem = new QStandardItem(headName);
    m_pModel->setHorizontalHeaderItem(index,pitem); //索引修改列名
}
/**
* @brief addRowData 添加行
* @param rowId 行Id
* @param rowData 行数据
* @return返回是否添加成功
*/
bool GY_IdTableView::addRowData(const QVariant &rowId, const QVector<QVariant> &rowData)
{
    if(m_RowDataInfoMap.contains(rowId)||!rowData.size()||!m_pModel->columnCount())
    {
        return false;
    }
    QList<QStandardItem*> rowItems; //用list容器存储item
    for(int i=0;i<m_pModel->columnCount();i++)
    {
        QStandardItem* pItem=new QStandardItem;
        if(i<rowData.size()) //如果插入的行数据的数量大于列数
        {
            pItem->setData(rowData[i]);
            pItem->setText(rowData[i].toString());
        }
        if(!i)
        {
            pItem->setData(rowId,TableDataType::RowIdData);
        }
        rowItems<<pItem;
    }
    m_RowDataInfoMap.insert(rowId,rowItems);
    m_pModel->appendRow(rowItems); //添加行
    return true;
}
/**
 * @brief insertRowData 插入行数据
 * @param rowIndex 插入行索引
 * @param rowId 插入的行Id
 * @param rowData 插入的行数据
 * @return 是否插入成功
 */
bool GY_IdTableView::insertRowData(const int rowIndex, const QVariant &rowId, const QVector<QVariant> &rowData)
{
    if(!rowData.size()||!m_pModel||!m_pModel->columnCount()||rowIndex>m_pModel->rowCount()) //插入行数据无效
    {
        return false;
    }
    QList<QStandardItem*> rowItems; //用list容器存储item
    for(int i=0;i<m_pModel->columnCount();i++)
    {
        QStandardItem* pItem=new QStandardItem;
        if(i<rowData.size())
        {
            pItem->setData(rowData[i]);
            pItem->setText(rowData[i].toString());
        }
        if(!i)
        {
            pItem->setData(rowId,TableDataType::RowIdData);
        }
        rowItems<<pItem;
    }
    m_RowDataInfoMap.insert(rowId,rowItems);
    m_pModel->insertRow(rowIndex,rowItems);
    return true;
}
/**
 * @brief deleteRow  删除指定行
 * @param rowId 删除行Id
 * @return 返回删除是否成功
 */
/**
 * @brief deleteRow  删除指定行
 * @param rowId 删除行Id
 * @return 返回删除是否成功
 */
bool GY_IdTableView::deleteRow(const QVariant &rowId)
{
    if(!m_RowDataInfoMap.contains(rowId)||!m_RowDataInfoMap.value(rowId).size())
    {
        return false;
    }
    //判定删除的行是否是选中行
    QList<QStandardItem*> removeItems=m_RowDataInfoMap.value(rowId);
    bool isSelect=false;
    for(int i=0;i<removeItems.size();i++)
    {
        if(removeItems.at(i)==m_pLastSelectItme)
        {
            m_pLastSelectItme = nullptr;
            isSelect=true;
            break;
        }
    }
    //删除行和行ID
    bool del = this->model()->removeRow(m_RowDataInfoMap.value(rowId).at(0)->row());
    m_RowDataInfoMap.remove(rowId);
    //如果是选中行发起更改选中信号
    if(isSelect)
    {
        QModelIndex selectIndex = this->currentIndex();
        QStandardItem * pSelectItme=m_pModel->itemFromIndex(selectIndex);
        if(m_pModel->item(selectIndex.row() > -1))
        {
            QVariant rowId=((QStandardItemModel*)this->model())->item(selectIndex.row())->data(TableDataType::RowIdData);
            m_pLastSelectItme=pSelectItme;
            emit selectCellChangeSignal(rowId,selectIndex.column());
            emit selectRowChangeSignal(rowId);
        }
    }
    return del;
}
/**
 * @brief setRowData  修改行数据
 * @param rowId 行Id
 * @param rowData  待修改的数据
 * @return 是否修改成功
 */
bool GY_IdTableView::setRowData(const QVariant &rowId, const QVector<QVariant> &rowData)
{
    if(!m_RowDataInfoMap.contains(rowId)||!m_RowDataInfoMap.value(rowId).size()) //修改行数据无效
    {
        return false;
    }
    for(int j=0;j<qMin(m_RowDataInfoMap.value(rowId).size(),rowData.size());j++)
    {
        QStandardItem* pNewRowItem = m_RowDataInfoMap.value(rowId).at(j);
        pNewRowItem->setData(rowData.at(j));
        pNewRowItem->setText(rowData.at(j).toString());
    }
    return true;
}
/**
 * @brief getRowData 获取行数据
 * @param rowId 行ID
 * @return 返回获取的行数据
 */
QVector<QVariant> GY_IdTableView::getRowData(const QVariant &rowId)
{
    QVector<QVariant> rowDataVec;
    if(!m_RowDataInfoMap.contains(rowId))
    {
        return rowDataVec;
    }
    QList<QStandardItem*> rowItmes=m_RowDataInfoMap.value(rowId);
    for(int i=0;i<rowItmes.size();i++)
    {
        rowDataVec<< rowItmes.at(i)->data(TableDataType::TransferData);
    }
    return rowDataVec;
}
/**
 * @brief setRowEnabled 设置行交互状态
 * @param rowId  行ID
 * @param isEnabled 是否可交互
 * @return 返回设置是否成功
 */
bool GY_IdTableView::setRowEnabled(const QVariant &rowId,const bool isEnabled)
{
    if(!m_RowDataInfoMap.contains(rowId))
    {
        return false;
    }
    QList<QStandardItem*> rowItems=m_RowDataInfoMap.value(rowId);
    for(int i=0;i<rowItems.size();i++)
    {
        rowItems.at(i)->setEnabled(isEnabled);
    }
    return true;
}
/**
 * @brief setRowEditabled 设置行编辑状态
 * @param rowId 行ID
 * @param isEditabled 是否可编辑
 * @return 返回设置是否成功
 */
bool GY_IdTableView::setRowEditabled(const QVariant &rowId, const bool isEditabled)
{
    if(!m_RowDataInfoMap.contains(rowId))
    {
        return false;
    }
    QList<QStandardItem*> rowItems=m_RowDataInfoMap.value(rowId);
    for(int i=0;i<rowItems.size();i++)
    {
        rowItems.at(i)->setEditable(isEditabled);
    }
    return true;
}
/**
 * @brief setTextCenter 设置文字居中显示
 * @param rowId 索引第几行
 * @return 返回设置是否成功
 */
bool GY_IdTableView::setTextCenter(const QVariant rowId)
{
    if(!m_RowDataInfoMap.contains(rowId))
    {
        return false;
    }
    for(int i=0;i<this->model()->columnCount();i++)
    {
        m_RowDataInfoMap.value(rowId).at(i)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    }
    return true;
}

/**
 * @brief GY_IdTableView::getRowIndex 获取行索引
 * @param rowId 行Id
 * @return 行索引
 */
int GY_IdTableView::getRowIndex(const QVariant &rowId)
{
    if(!m_RowDataInfoMap.contains(rowId)){
        return -1;
    }
    return m_RowDataInfoMap.value(rowId)[0]->row();
}
/**
 * @brief setCellColor 修改item背景颜色
 * @param rowId 行id
 * @param columnIndex 列
 * @param color 颜色
 * @return 是否修改成功
 */
bool GY_IdTableView::setCellColor(const QVariant &rowId, const int columnIndex,const QColor& color)
{
    if(!m_RowDataInfoMap.contains(rowId)||columnIndex>=m_RowDataInfoMap.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    QBrush abrush;
    abrush.setColor(color);
    m_RowDataInfoMap.value(rowId).at(columnIndex)->setBackground(abrush);
    return true;
}
/**
 * @brief setCellData  修改单元格数据
 * @param rowId 修改行Id
 * @param columnIndex  修改列索引
 * @param cellData  要修改的数据
 * @param role 修改的数据类型
 * @return 是否修改成功
 */
bool GY_IdTableView::setCellData(const QVariant &rowId, const int columnIndex, const QVariant &cellData, int role)
{
    if(!m_RowDataInfoMap.contains(rowId)||columnIndex>=m_RowDataInfoMap.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    m_RowDataInfoMap.value(rowId).at(columnIndex)->setData(cellData,role);
    return true;
}
/**
 * @brief setCellText 设置单元格文字
 * @param rowId 行ID
 * @param columnIndex 列索引
 * @param displayText 显示文字
 * @return 是否设置成功
 */
bool GY_IdTableView::setCellText(const QVariant &rowId, const int columnIndex, const QString &displayText)
{
    return setCellData(rowId,columnIndex,displayText,TableDataType::DisplayData);
}
/**
 * @brief getCellData 获取单元格数据
 * @param rowId 行ID
 * @param columnIndex 列索引
 * @return 单元格数据
 */
QVariant GY_IdTableView::getCellData(const QVariant &rowId, const int columnIndex,int role)
{
    QVariant cellData;
    if(!m_RowDataInfoMap.contains(rowId)||columnIndex>=m_RowDataInfoMap.value(rowId).size()||columnIndex<0)
    {
        return cellData;
    }
    cellData=m_RowDataInfoMap.value(rowId).at(columnIndex)->data(role);
    return cellData;
}
/**
 * @brief getCellText 获取单元格文字
 * @param rowId 行ID
 * @param columnIndex 列索引
 * @return 单元格文字
 */
QString GY_IdTableView::getCellText(const QVariant &rowId, const int columnIndex)
{
    return getCellData(rowId,columnIndex,TableDataType::DisplayData).toString();
}
/**
 * @brief setCellEnabled 设置行交互状态
 * @param rowId  行ID
 * @param columnIndex 列索引
 * @param isEnabled 是否可交互
 * @return 返回设置是否成功
 */
bool GY_IdTableView::setCellEnabled(const QVariant &rowId, const int columnIndex, const bool isEnabled)
{
    if(!m_RowDataInfoMap.contains(rowId)||columnIndex>=m_RowDataInfoMap.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    m_RowDataInfoMap.value(rowId).at(columnIndex)->setEnabled(isEnabled);
    return true;
}
/**
 * @brief setCellEditabled 设置行编辑状态
 * @param rowId  行ID
 * @param columnIndex 列索引
 * @param isEnabled 是否可编辑
 * @return 返回设置是否成功
 */
bool GY_IdTableView::setCellEditabled(const QVariant &rowId, const int columnIndex, const bool isEditabled)
{
    if(!m_RowDataInfoMap.contains(rowId)||columnIndex>=m_RowDataInfoMap.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    m_RowDataInfoMap.value(rowId).at(columnIndex)->setEditable(isEditabled);
    return true;
}
/**
 * @brief getSelectRowIndex  获取选择行Id
 * @return  多选下返回选中的行Id
 */
QVariant GY_IdTableView::getSelectRowId()
{
    return  this->currentIndex().siblingAtColumn(0).data(TableDataType::RowIdData);
}
/**
 * @brief setSelectRow 设置选择行
 * @param rowId 设置选择的ID
 * @return 是否设置成功
 */
bool GY_IdTableView::setSelectRow(const QVariant &rowId)
{
    if(!m_RowDataInfoMap.contains(rowId)||m_RowDataInfoMap.value(rowId).size()<=0)
    {
        return false;
    }
    this->setCurrentIndex(m_RowDataInfoMap.value(rowId).at(0)->index());
    return true;
}
/**
 * @brief setSelectCell 设置选中单元格
 * @param rowId 设置单元格的行ID
 * @param columnIndex 设置单元格的列索引
 * @return 是否设置成功
 */
bool GY_IdTableView::setSelectCell(const QVariant &rowId, const int columnIndex)
{
    if(!m_RowDataInfoMap.contains(rowId)||columnIndex>=m_RowDataInfoMap.value(rowId).size()||columnIndex<0)
    {
        return false;
    }
    this->setCurrentIndex(m_RowDataInfoMap.value(rowId).at(columnIndex)->index());
    return true;
}
/**
 * @brief clearData 清除所有数据
 */
void GY_IdTableView::clearData()
{
    m_pModel->clear();
    m_RowDataInfoMap.clear();
}

/**
 * @brief GY_IdTableView::setFilterRegExp 设置搜索过滤正则表达式
 * @param searchText 搜索过滤文本
 */
void GY_IdTableView::setFilterRegExp(const QString &searchText)
{
    m_pFilter->setFilterRegExp(searchText);
}

void GY_IdTableView::setFilterColumn(const int column)
{
    m_pFilter->setFilterKeyColumn(column);
}

void GY_IdTableView::findTargetRow(const QMap<int, QString> &dataMap)
{
    QList<QVariant> targetRowsList;
    QMap<int, QString> colInfo = dataMap;
    for(int row = 0; row < m_pModel->rowCount(); row++)
    {
        bool found = true;
        for(QMap<int, QString>::iterator itor= colInfo.begin(); itor != colInfo.end();)
        {
            int col = itor.key();
            QString searchString = itor.value();
            QStandardItem* pItem= m_pModel->item(row,col);
            if(!pItem || !pItem->data(TableDataType::DisplayData).toString().contains(searchString))
            {
                found = false;
                //!存在行ID
                QStandardItem* rowIDitem = m_pModel->item(row,0);
                if(rowIDitem)
                {
                    QVariant index = rowIDitem->data(TableDataType::RowIdData);
                    targetRowsList.append(index);
                }
                break;
            }
            itor++;
        }
    }
    for(int i =0; i < targetRowsList.size();i++)
    {
        deleteRow(targetRowsList.at(i));
    }
}

bool GY_IdTableView::isAllAccordWith(const int &row, const QMap<int, QString> &colInfoMap, const QStringList &conditionList)
{
    QMap<int, QString> colInfo = colInfoMap;
    for(QMap<int, QString>::iterator colItor= colInfo.begin(); colItor != colInfo.end();)
    {
        QStandardItem *item = m_pModel->item(row,colItor.key());
        if(item)
        {
            for(int i = 0; i < conditionList.size(); i++)
            {
                QString showStr = item->data(TableDataType::DisplayData).toString();
                if(showStr.contains(conditionList.at(i)))
                    return true;
            }
        }
        colItor++;
    }
    return false;
}


/**
 * @brief GY_IdTableView::dataChangedSlot 单元格内容改变
 * @param topLeft
 * @param bottomRight
 * @param roles
 */
void GY_IdTableView::dataChangedSlot(QStandardItem *item)
{
    //判定是否是二次更新
    if(item->data(TableDataType::DisplayData)==item->data(TableDataType::TransferData))
    {
        return;
    }
    item->setData(item->data(TableDataType::DisplayData),TableDataType::TransferData);
    QVariant rowId = item->index().siblingAtColumn(0).data(TableDataType::RowIdData);
    int column = item->index().column();
    QVariant value = item->data();
    emit sgl_CellValueChangeSignal(rowId,column,value);
}

/**
 * @brief mousePressEvent 鼠标事件
 * @param event 事件指针
 */
void GY_IdTableView::mousePressEvent(QMouseEvent *event)
{
    switch((int)event->button())
    {
    case Qt::MouseButton::LeftButton:
    {
        QModelIndex selectIndex = indexAt(event->pos());
        QStandardItem * pSelectItme=m_pModel->item(selectIndex.row(),selectIndex.column());
        if(!pSelectItme)
        {
            break;
        }
        QVariant rowId=m_pModel->item(selectIndex.row())->data(TableDataType::RowIdData);
        QModelIndex lastSelectIndex;
        if(m_pLastSelectItme)
        {
            lastSelectIndex=m_pLastSelectItme->index();
        }
        if(pSelectItme!=m_pLastSelectItme)
        {
            m_pLastSelectItme=pSelectItme;
            emit selectCellChangeSignal(rowId,selectIndex.column());
        }
        if(!m_pLastSelectItme||lastSelectIndex.row()!=selectIndex.row())
        {
            emit selectRowChangeSignal(rowId);
        }
    }break;
    }
    QTableView::mousePressEvent(event);
}
